#ifndef BNETPACKETSNIFFERWORKERTHREAD
#define BNETPACKETSNIFFERWORKERTHREAD


// WIN32 is checked by pcap.h 
#ifdef Q_OS_WIN
#  ifndef WIN32
#    define WIN32
#  endif
#endif

// // DEBUG:
// #include <fstream>
// #include <string>
// using namespace std;




#include <pcap.h>

#include <qthread.h>
#include <qwaitcondition.h>
#include <qcstring.h>

class PacketSnifferWorkerThread : public QThread
{
 public:
    PacketSnifferWorkerThread( QWaitCondition* notify,
			       pcap_if_t* device,
			       const int& timeout = 100, // Milliseconds.
			       const int& mode = 1, // Promiscuous.
			       const QString& filter = "",
			       const bool& tcpOnly = false,
			       const int& packetPortion = 65536 );
    ~PacketSnifferWorkerThread();
    
    QByteArray getByteArray();
    bool initSuccess() const;
    bool packetReady() const;
    int getDataLinkType() const;

    // These handlers return the IP packet for their data link (dl) type.
    QByteArray handle_dl_null( const struct pcap_pkthdr* header, 
			       const unsigned char* p );

    QByteArray handle_dl_raw( const struct pcap_pkthdr* header, 
			      const unsigned char* p );

    QByteArray handle_dl_ethernet( const struct pcap_pkthdr* header, 
				   const unsigned char* p );

    QByteArray handle_dl_ppp( const struct pcap_pkthdr* header, 
			      const unsigned char* p );

    QByteArray handle_dl_linux_sll( const struct pcap_pkthdr* header, 
				    const unsigned char* p );
    
    bool checkValidIPPacket( const unsigned char* data, 
			     const unsigned int& caplen );
    
    QByteArray stripTCP( const QByteArray& IPpacket );
 protected:
    void run();
    
 private:
    // Unimplemented functions:
    PacketSnifferWorkerThread( const PacketSnifferWorkerThread& );
    PacketSnifferWorkerThread& 
	operator=( const PacketSnifferWorkerThread& );

    // Constants.
    const int NULL_HDRLEN;
    const int PPP_HDRLEN;
    const int SLL_HDRLEN;

    // Stored member variables.
    bool initSuccess_;
    char errbuf[PCAP_ERRBUF_SIZE];
    QByteArray bytes_;
    QWaitCondition* notify_;
    pcap_if_t* device_;
    int timeout_;
    int mode_;
    bool tcpOnly_;  // Filter out the IP headers and TCP_headers.
    int packetPortion_;
    
    pcap_t *adhandle_;

    // For filtering:
    u_int netmask_;
    char* filterStr_;
    struct bpf_program fcode_;
    int dataLinkType_;

//     // DEBUG:
//     ofstream debugworker;
//     string print_hex_form(unsigned char x);
//     void print_qbytearray( const QByteArray& arr );
};



#endif
